using System;

using Microsoft.SPOT;

using mfRCF.Core;
using mfRCF.Core.Extensions;

using mfXmlSerializer;

using mfLogger;

using OST.Shared.SharedTypes;
using OST.Persistence;
using OST.Shared;
using System.Text;

namespace OST.Commands
{
    using Extensions;
    using System.IO;

    /// <summary>
    /// saves/overwrites the actual xml-serialized-Configuration and persists it
    /// </summary>
    /// <remarks>throws OutOfMemoryException on netuinoplus2, caus of XmlReader</remarks>
    public class ConfigurationPOSTCommand : mfRcfCommand
    {
        #region CTOR

        public ConfigurationPOSTCommand(string httpPath)
            : base(httpPath, new mfPOSTMethod())
        {
        }

        #endregion

        #region Properties

        /// <summary>
        /// wrapper-property 4 logging
        /// </summary>
        private ILoggerAppender Logger
        {
            get
            {
                return mfLogger.mfLogger.Instance;
            }
        }

        #endregion

        #region mfRcfCommand
        public override void ExecuteCommand(mfIHttpContext httpContext)
        {
            try
            {
                if (!RemoveableMediaStorageProvider.Instance.IsStorageConntected)
                    throw new OSTException("no storage connected");

                var configSerializer = new mfXmlTypedSerializer(typeof(Configuration));

                //read to the end of the HttpListenerRequest.InputStream
                var msStream = new MemoryStream();
                var inputLength = 0;
                do
                {
                    var inputBytes = httpContext.Request.InputStream.ReadAllBytes();
                    inputLength = inputBytes.Length;
                    msStream.Write(inputBytes, 0, inputBytes.Length);
                    inputBytes = null;
                }
                while (httpContext.Request.InputStream.Length != inputLength);

                var newXmlConfig = msStream.ReadAllText();
                msStream.Dispose();

                //deserialize new config (from tmp-file)
                var newConfig = (Configuration)configSerializer.Deserialize(newXmlConfig);

                configSerializer.Dispose();
                Logger.Debug(GetType() + " xml readed, " + Debug.GC(true) + " bytes free");

                //validate new config
                newConfig.Validate();

                //set new config in provider
                ConfigurationProvider.Instance.ConfigInstance = newConfig;

                //persist new config
               ConfigurationProvider.Instance.SaveConfiguration();

                this.WriteHttpResponseOK(httpContext);
            }
            catch (Exception ex)
            {
                this.WriteHttpResponseError(httpContext, ex);
            }
        } 
        #endregion
    }
}
